package resource

import (
	"fmt"
	"go.getaway.adminspro.padmins.com/untils"
	"go.getaway.adminspro.padmins.com/untils/handler"
	"strconv"
	"strings"
)

func Index(c *handler.Handler) (map[string]interface{}, untils.Error) {
	where, bindValue, limit, order, e := c.BusinessCommonQuery.Build()

	if e != nil {
		return nil, untils.BusinessErrorf(e.Error())
	}

	total, _ := c.Db.Find(fmt.Sprintf("select count(*) total from admin_resource where 1=1 %s", where), bindValue...)
	rows, e := c.Db.Query(fmt.Sprintf("select * from admin_resource where 1=1 %s %s %s", where, order, limit), bindValue...)
	if e != nil {
		return nil, untils.NewBusinessError(2000, e.Error())
	}
	ids := untils.ArrayColumn(rows, "id")
	for _, row := range rows {
		c.ListFormat(list(), row)
		if row["resource"].(string) == "" {
			row["resource"] = strings.ReplaceAll(row["path"].(string), "/", ".")
		}
		row["name"] = row["title"]

		if !untils.InArray(row["pid"], ids) {
			row["pid"] = 0
		}
	}

	return map[string]interface{}{"total": total["total"], "rows": rows}, nil
}

func List(c *handler.Handler) (map[string]interface{}, untils.Error) {
	return list(), nil
}

func list() map[string]interface{} {
	return map[string]interface{}{
		"type":   map[string]interface{}{"1": "菜单", "2": "节点"},
		"status": map[string]interface{}{"1": "正常", "0": "隐藏"},
	}
}

func Detail(c *handler.Handler) (map[string]interface{}, untils.Error) {
	params := map[string]string{
		"id": c.Request.Params("id", "").(string),
	}

	row, e := c.Db.Find("select * from admin_resource where id=?", params["id"])

	if e != nil {
		return nil, untils.NewBusinessError(2000, e.Error())
	}

	if row == nil {
		return nil, untils.BusinessErrorf("未找到记录")
	}

	if row["resource"].(string) == "" {
		row["resource"] = strings.ReplaceAll(row["path"].(string), "/", ".")
	}

	c.ListFormat(list(), row)

	resources, e := c.Db.Query("select *,title as name from admin_resource")

	if e != nil {
		return nil, untils.NewBusinessError(2000, e.Error())
	}
	t := untils.NewTree()
	resources = t.Init(resources).GetTreeArray(int64(0))

	titles := []string{}

	for _, title := range untils.ArrayColumn(t.GetParents(row["id"]), "title") {
		titles = append(titles, title.(string))
	}

	row["pid_text"] = untils.Implode("/", titles)

	ids := t.GetChildrenIds(row["id"], true)
	resources = t.GetTreeList(resources, "name")

	menus := []map[string]interface{}{}
	for _, resource := range resources {
		resource["disabled"] = untils.InArray(resource["id"], ids)
		if resource["type"] == int64(1) {
			menus = append(menus, resource)
		}
	}
	return map[string]interface{}{
		"row":   row,
		"menus": menus,
	}, nil
}

func Add(c *handler.Handler) (map[string]interface{}, untils.Error) {
	params := map[string]string{
		"pid":      c.Request.Params("pid", "").(string),
		"type":     c.Request.Params("type", "").(string),
		"path":     c.Request.Params("path", "").(string),
		"resource": c.Request.Params("resource", "").(string),
		"title":    c.Request.Params("title", "").(string),
		"icon":     c.Request.Params("icon", "").(string),
		"remark":   c.Request.Params("remark", "").(string),
		"badge":    c.Request.Params("badge", "").(string),
		"weigh":    c.Request.Params("weigh", "0").(string),
		"status":   c.Request.Params("status", "1").(string),
	}

	if params["pid"] == "" {
		return nil, untils.BusinessErrorf("Invalid param pid")
	}
	if !untils.InArray(params["type"], []interface{}{"1", "2"}) {
		return nil, untils.BusinessErrorf("Invalid param type")
	}
	if params["path"] == "" {
		return nil, untils.BusinessErrorf("Invalid param path")
	}
	if params["resource"] == "" {
		return nil, untils.BusinessErrorf("Invalid param resource")
	}
	if params["title"] == "" {
		return nil, untils.BusinessErrorf("Invalid param title")
	}
	if params["weigh"] == "" {
		return nil, untils.BusinessErrorf("Invalid param weigh")
	}
	if !untils.InArray(params["status"], []interface{}{"0", "1"}) {
		return nil, untils.BusinessErrorf("Invalid param status")
	}

	if pid, _ := strconv.Atoi(params["pid"]); pid > 0 {
		hasPid, _ := c.Db.Find("select * from admin_resource where type=1 and id=?", pid)
		if hasPid == nil {
			return nil, untils.BusinessErrorf("pid菜单不存在")
		}
	}

	hasPath, _ := c.Db.Find("select * from admin_resource where path=?", params["path"])
	if hasPath != nil {
		return nil, untils.BusinessErrorf("路径已存在")
	}

	hasResource, _ := c.Db.Find("select * from admin_resource where resource=?", params["resource"])
	if hasResource != nil {
		return nil, untils.BusinessErrorf("资源已存在")
	}

	Result, e := c.Db.Execute("insert into admin_resource(pid, type, path, resource, title, icon, remark, badge, weigh, status, create_time, update_time)"+
		"values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", []interface{}{
		params["pid"],
		params["type"],
		params["path"],
		params["resource"],
		params["title"],
		params["icon"],
		params["remark"],
		params["badge"],
		params["weigh"],
		params["status"],
		untils.Date("Y-m-d H:i:s"),
		untils.Date("Y-m-d H:i:s"),
	}...)

	if e != nil {
		return nil, untils.NewBusinessError(2000, "操作失败")
	}
	if LastInsertId, e := Result.LastInsertId(); e != nil {
		return nil, untils.NewBusinessError(2000, "操作失败")
	} else {
		return map[string]interface{}{
			"row": map[string]int64{
				"id": LastInsertId,
			},
		}, nil
	}

}

func Edit(c *handler.Handler) (map[string]interface{}, untils.Error) {
	params := map[string]string{
		"id":       c.Request.Params("id", "").(string),
		"pid":      c.Request.Params("pid", "").(string),
		"type":     c.Request.Params("type", "").(string),
		"path":     c.Request.Params("path", "").(string),
		"resource": c.Request.Params("resource", "").(string),
		"title":    c.Request.Params("title", "").(string),
		"icon":     c.Request.Params("icon", "").(string),
		"remark":   c.Request.Params("remark", "").(string),
		"badge":    c.Request.Params("badge", "").(string),
		"weigh":    c.Request.Params("weigh", "0").(string),
		"status":   c.Request.Params("status", "1").(string),
	}

	if params["pid"] == "" {
		return nil, untils.BusinessErrorf("Invalid param pid")
	}
	if !untils.InArray(params["type"], []interface{}{"1", "2"}) {
		return nil, untils.BusinessErrorf("Invalid param type")
	}
	if params["path"] == "" {
		return nil, untils.BusinessErrorf("Invalid param path")
	}
	if params["resource"] == "" {
		return nil, untils.BusinessErrorf("Invalid param resource")
	}
	if params["title"] == "" {
		return nil, untils.BusinessErrorf("Invalid param title")
	}
	if params["weigh"] == "" {
		return nil, untils.BusinessErrorf("Invalid param weigh")
	}
	if !untils.InArray(params["status"], []interface{}{"0", "1"}) {
		return nil, untils.BusinessErrorf("Invalid param status")
	}

	if pid, _ := strconv.Atoi(params["pid"]); pid > 0 {
		hasPid, _ := c.Db.Find("select * from admin_resource where type=1 and id=?", pid)
		if hasPid == nil {
			return nil, untils.BusinessErrorf("pid菜单不存在")
		}
		rows, _ := c.Db.Query("select * from admin_resource where type=1")
		id, _ := strconv.Atoi(params["id"])
		ChildrenIds := untils.NewTree().Init(rows).GetChildrenIds(int64(id), true)
		if untils.InArray(int64(pid), ChildrenIds) {
			return nil, untils.BusinessErrorf("pid菜单不能为自己id或者是下级id在")
		}
	}

	hasPath, _ := c.Db.Find("select * from admin_resource where path=? and id<>?", params["path"], params["id"])
	if hasPath != nil {
		return nil, untils.BusinessErrorf("路径已存在")
	}

	hasResource, _ := c.Db.Find("select * from admin_resource where resource=? and id<>?", params["resource"], params["id"])
	if hasResource != nil {
		return nil, untils.BusinessErrorf("资源已存在")
	}

	row, _ := c.Db.Find("select * from admin_resource where id=?", params["id"])
	if row == nil {
		return nil, untils.BusinessErrorf("未找到记录")
	}

	Result, e := c.Db.Execute("update admin_resource set pid=?,type=?,path=?,resource=?,"+
		"title=?,icon=?,remark=?,badge=?,weigh=?,status=?,update_time=? where id=?", []interface{}{
		params["pid"],
		params["type"],
		params["path"],
		params["resource"],
		params["title"],
		params["icon"],
		params["remark"],
		params["badge"],
		params["weigh"],
		params["status"],
		untils.Date("Y-m-d H:i:s"),
		row["id"],
	}...)

	if e != nil {
		return nil, untils.NewBusinessError(2000, "操作失败")
	}

	RowsAffected, e := Result.RowsAffected()

	if e != nil {
		return nil, untils.NewBusinessError(2000, "操作失败")
	}

	if RowsAffected <= 0 {
		return nil, untils.NewBusinessError(2000, "操作失败")
	}

	return map[string]interface{}{}, nil
}

func Del(c *handler.Handler) (map[string]interface{}, untils.Error) {
	params := map[string]string{
		"id": c.Request.Params("id", "").(string),
	}

	ids := strings.Split(params["id"], ",")

	if len(ids) < 0 {
		return nil, untils.BusinessErrorf("id参数不能为空")
	}

	rows, e := c.Db.Query("select * from admin_resource")

	if e != nil {
		return nil, untils.NewBusinessError(2000, e.Error())
	}

	t := untils.NewTree().Init(rows)

	ChildrenIds := []interface{}{}

	for _, id := range ids {
		id, _ := strconv.Atoi(id)
		ChildrenIds = append(ChildrenIds, t.GetChildrenIds(int64(id), true)...)
	}

	if len(ChildrenIds) == 0 {
		return nil, untils.BusinessErrorf("操作失败，数据不存在")
	}

	Result, e := c.Db.Execute("delete from admin_resource where id in (?)", ChildrenIds)

	if e != nil {
		return nil, untils.NewBusinessError(2000, e.Error())
	}
	RowsAffected, e := Result.RowsAffected()

	if e != nil {
		return nil, untils.BusinessErrorf("操作失败")
	}

	if RowsAffected <= 0 {
		return nil, untils.BusinessErrorf("操作失败")
	}

	return map[string]interface{}{}, nil
}

func Multi(c *handler.Handler) (map[string]interface{}, untils.Error) {
	return nil, untils.BusinessErrorf("接口不能操作")
}
